﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using Moonlite.Services.CodeCompletion;
using Storm.TextEditor.Editor.Text;
namespace Moonlite.UI.Shell.Controls {
    public partial class QuickLinksControl : UserControl {
        private bool updating;
        private AndromedaSource currentSource;
        private TextEditor textEditor;
        public TextEditor TextEditor {
            get { return textEditor; }
            set { textEditor = value; }
        }
        private void OnTypesClosed(object sender, ClosedEventArgs e) {
            if (e.CloseMode == PopupCloseMode.Normal) {
                ImageComboBoxItem item = (ImageComboBoxItem)comboBoxTypes.SelectedItem;
                if (item == null) return;
                AndromedaObject @object = (AndromedaObject)item.Value;
                if (@object == null) return;
                NavigateToOffset(@object.Offset - currentSource.TagLength);
            }
        }
        private void OnMembersClosed(object sender, ClosedEventArgs e) {
            if (e.CloseMode == PopupCloseMode.Normal) {
                ImageComboBoxItem item = (ImageComboBoxItem)comboBoxMembers.SelectedItem;
                if (item == null) return;
                AndromedaObject @object = (AndromedaObject)item.Value;
                if (@object == null) return;
                NavigateToOffset(@object.Offset - currentSource.TagLength);
            }
        }
        public void ShowTypesDropDown() {
            comboBoxTypes.ShowPopup();
            comboBoxTypes.Focus();
        }
        public void ShowMembersDropDown() {
            comboBoxMembers.ShowPopup();
            comboBoxMembers.Focus();
        }
        public void UpdateListsToMatchCurrentObject() {
            if (currentSource == null || textEditor == null) return;
            IAndromedaObjectWithType type = null;
            AndromedaObjectClass @class = GalaxyObjectHelper.GetCurrentClass(currentSource, textEditor, currentSource.TagLength);
            AndromedaObjectEnrichment enrichment = GalaxyObjectHelper.GetCurrentEnrichment(currentSource, textEditor, currentSource.TagLength);
            AndromedaObjectStruct @struct = GalaxyObjectHelper.GetCurrentStruct(currentSource, textEditor, currentSource.TagLength);
            if (@class != null) {
                type = @class;
            }
            else if (enrichment != null) {
                type = enrichment;
            }
            else if (@struct != null) {
                type = @struct;
            }
            if (type != null) {
                foreach (ImageComboBoxItem item in comboBoxTypes.Properties.Items) {
                    if (item.Value == type) {
                        comboBoxTypes.SelectedItem = item;
                        break;
                    }
                }
                IAndromedaMemberOfType member = null;
                AndromedaObjectField field = GalaxyObjectHelper.GetCurrentField(currentSource, textEditor, currentSource.TagLength);
                AndromedaObjectMethod method = GalaxyObjectHelper.GetCurrentMethod(currentSource, textEditor, currentSource.TagLength);
                AndromedaObjectProperty property = GalaxyObjectHelper.GetCurrentProperty(currentSource, textEditor, currentSource.TagLength);
                if (field != null) {
                    member = field;
                }
                else if (method != null) {
                    member = method;
                }
                else if (property != null) {
                    member = property;
                }
                if (member != null) {
                    foreach (ImageComboBoxItem item in comboBoxMembers.Properties.Items) {
                        if (item.Value == member) {
                            comboBoxMembers.SelectedItem = item;
                            break;
                        }
                    }
                }
            }
        }
        public void UpdateSource(AndromedaSource source) {
            currentSource = source;
            if (currentSource.Children.Count > 0 && (!comboBoxTypes.IsPopupOpen && !comboBoxMembers.IsPopupOpen) && !updating) {
                updating = true;
                comboBoxTypes.Properties.Items.BeginUpdate();
                comboBoxTypes.Properties.Items.Clear();
                foreach (AndromedaObject @object in currentSource.Children) {
                    if (@object is IAndromedaObjectWithType) {
                        IAndromedaObjectWithType objectWithType = (IAndromedaObjectWithType)@object;
                        if (objectWithType.Type == AndromedaObjectOopType.Class) {
                            AndromedaObjectClass @class = (AndromedaObjectClass)@object;
                            comboBoxTypes.Properties.Items.Add(new ImageComboBoxItem(@class, @class.ImageIndex));
                        }
                        else if (objectWithType.Type == AndromedaObjectOopType.Enrichment) {
                            AndromedaObjectEnrichment enrichment = (AndromedaObjectEnrichment)@object;
                            comboBoxTypes.Properties.Items.Add(new ImageComboBoxItem(enrichment, enrichment.ImageIndex));
                        }
                        else if (objectWithType.Type == AndromedaObjectOopType.Struct) {
                            AndromedaObjectStruct @struct = (AndromedaObjectStruct)@object;
                            comboBoxTypes.Properties.Items.Add(new ImageComboBoxItem(@struct, @struct.ImageIndex));
                        }
                    }
                }
                if (comboBoxTypes.Properties.Items.Count > 0 && comboBoxTypes.SelectedIndex == -1) {
                    comboBoxTypes.SelectedIndex = 0;
                }
                comboBoxTypes.Properties.Items.EndUpdate();
                comboBoxTypes.Properties.Sorted = true;
                comboBoxMembers.Properties.Sorted = true;
                UpdateListsToMatchCurrentObject();
                updating = false;
            }
        }
        private void NavigateToOffset(int offset) {
            if (textEditor != null && !updating) {
                TextPoint point = textEditor.InnerTextEditor.Document.IntPosToPoint(offset);
                textEditor.InnerTextEditor.Caret.Position = point;
                textEditor.InnerTextEditor.Caret.CropPosition();
                textEditor.InnerTextEditor.ActiveViewControl.CenterInView(textEditor.InnerTextEditor.Caret.Position.Y);
                textEditor.InnerTextEditor.Focus();
            }
        }
        private void OnTypesSelectedIndexChanged(object sender, EventArgs e) {
            ImageComboBoxItem item = (ImageComboBoxItem)comboBoxTypes.SelectedItem;
            if (item == null) return;
            AndromedaObject @object = (AndromedaObject)item.Value;
            if (@object == null) return;
            IAndromedaObjectWithType objectWithType = (IAndromedaObjectWithType)@object;
            if (objectWithType != null) {
                if (@object.Children.Count > 0) {
                    comboBoxMembers.Properties.Items.BeginUpdate();
                    comboBoxMembers.Properties.Items.Clear();
                    foreach (AndromedaObject child in @object.Children) {
                        if (child is IAndromedaObjectWithName && child is IAndromedaObjectWithImageIndex) {
                            comboBoxMembers.Properties.Items.Add(new ImageComboBoxItem(child, ((IAndromedaObjectWithImageIndex)child).ImageIndex));
                        }
                    }
                    if (comboBoxMembers.Properties.Items.Count > 0 && comboBoxMembers.SelectedIndex == -1) {
                        comboBoxMembers.SelectedIndex = 0;
                    }
                    comboBoxMembers.Properties.Items.EndUpdate();
                }
            }
        }
        public QuickLinksControl() {
            InitializeComponent();
            comboBoxTypes.Properties.SmallImages = AndromedaImageIndexes.GlobalImageList;
            comboBoxMembers.Properties.SmallImages = AndromedaImageIndexes.GlobalImageList;
        }
    }
}
